﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebUtils;

namespace OAuth.AuthLocations
{
    public sealed class AuthHeader : AuthInfoLocation
    {
        private static AuthHeader instance;
        public static AuthHeader Instance
        {
            get
            {
                if (instance == null)
                    instance = new AuthHeader();
                return instance;
            }
        }

        private AuthHeader()
        {
        }

        public override string Name { get { return "Authorization HTTP Header"; } }

        public override ISignedWebRequest CreateSignedRequest(
            IUnsignedWebRequest pUnsignedWebRequest, 
            IEnumerable<UnEncodedURLParameter> pOAuthParameters )
        {
            return new DefaultSignedWebRequest()
            {
                Address = pUnsignedWebRequest.Address,
                GetParameters = pUnsignedWebRequest.GetParameters,
                Headers = pUnsignedWebRequest.Headers.Concat(CreateAuthHeader(pUnsignedWebRequest.Realm, pOAuthParameters)),
                PostParameters = pUnsignedWebRequest.PostParameters,
                UnsignedWebRequest = pUnsignedWebRequest,
                Verb = pUnsignedWebRequest.Verb
            };
        }

        private static IEnumerable<Parameter> CreateAuthHeader(string pRealm, IEnumerable<UnEncodedURLParameter> pOAuthParameters )
        {
            var value = new StringBuilder();
            value.AppendFormat("OAuth realm=\"{0}\"", pRealm);
            pOAuthParameters
                .EncodeParameters()
                .ForEach(param =>
                    {
                        value.AppendFormat(
                            ", {0}=\"{1}\"",
                            param.Key,
                            param.Value);
                    });

            yield return new Parameter()
            {
                Key = "Authorization",
                Value = value.ToString()
            };
            yield break;
        }
   }
}
